#!/usr/bin/env python
# -*- encoding: utf-8 -*-
'''
@File    :   Electrial_test.py
@Time    :   2023/12/21 13:31:28
@Author  :   YangLiang 
@Version :   1.0
@Contact :   yangliang@chengtech.com
@License :   (C)Copyright 2023-2026
@Desc    :   None
'''

# here put the import lib
from pytest_assume.plugin import assume
 
import pytest
import binascii
import logging
import time
import Set_up
from commDriver.modbus_plc import *
from sympy import I
# from sympy import assuming
from commDriver.TS_CAN import *
import allure
import sys
from collections.abc import Iterable

from sqlalchemy import false
sys.dont_write_bytecode = True



@allure.severity('critical')
class Test_Electrical_inspection_for_CAR(object):
   '''
   软件在每次发布版本前进行一定cycle的测试:
   需要按照整车实际总线负载进行模拟,第一次测试相关功能修改1000cycle,常规500cycle
   ''' 

   @allure.severity('normal')
   @allure.story('Write data by identifier test')
   @allure.title('Test 2100 of Write data by identifier 0x2E')
   @allure.testcase('Test cases address:https://chengtech.pingcode.com/testhub/libraries/630357052177ea2394680877/cases')
   @pytest.mark.repeat(200)
   def test_electrical_inspection_on_car(self, action, Driver):
      Driver['CAN'].wakeup_ctrl(True)
      iStep = 1
      VariantCoding = ''
      VariantCoding = Set_up.VariantCoding[0]

      for i in range(2):
         if i > 0 and len(Set_up.VariantCoding) > 1:
            VariantCoding = Set_up.VariantCoding[1]
         iStep,uds_resp, size = Driver['CAN'].checkReqResp(Driver, "10 03", "50 03", 1, iStep, False, 'UDS', 'ClearFault')
         self.checkFailureStatus(Driver, iStep)
         Driver['CAN'].checkReqResp(Driver, "2E F1 A1 FF FF FF FF FF FF FF FF", '6E F1 A1', 0, iStep, True)
         iStep,uds_resp, size = Driver['CAN'].checkReqResp(Driver, '2E 21 00 ' + VariantCoding, '6E 21 00', 0, iStep, False)
         iStep,uds_resp, size = Driver['CAN'].checkReqResp(Driver, '22 21 00', '62 21 00 ' + VariantCoding, 0, iStep, False)
         if i == 0:
            # 掉电重启后读取写入数据是否正常
            iStep = Driver['CAN'].restartMRR_Power(Driver, iStep)
         else:
            # 1101重启后读取写入数据是否正常
            iStep = Driver['CAN'].restartMRR_11(Driver, iStep)
         iStep,uds_resp, size = Driver['CAN'].checkReqResp(Driver, '22 21 00', '62 21 00 ' + VariantCoding, 3, iStep, False)
         Driver['CAN'].checkReqResp(Driver, "2E F1 A1 FF FF FF FF FF FF FF FF", '6E F1 A1', 0, iStep, True)
         iStep,uds_resp, size = Driver['CAN'].checkReqResp(Driver, "19 02 09", "59 02 09", 0, iStep, False, 'UDS', 'ClearFault')
         iStep = Driver['CAN'].delInitialFailure(iStep,uds_resp)
      
      Driver['CAN'].wakeup_ctrl(False)


   @allure.severity('normal')
   @allure.story('Write data by identifier test')
   @allure.title('Test 2100 of Write data by identifier 0x2E')
   @allure.testcase('Test cases address:https://chengtech.pingcode.com/testhub/libraries/630357052177ea2394680877/cases')
   @pytest.mark.repeat(20)
   def test_electrical_inspection_on_car_NoReset(self, action, Driver):
      Driver['CAN'].wakeup_ctrl(True)
      iStep = 1
      VariantCoding = ''
      VariantCoding = Set_up.VariantCoding[0]

      for i in range(10):
         if i > 0 and len(Set_up.VariantCoding) > 1:
            VariantCoding = Set_up.VariantCoding[1]
         iStep,uds_resp, size = Driver['CAN'].checkReqResp(Driver, "10 03", "50 03", 1, iStep, False, 'UDS', 'ClearFault')
         self.checkFailureStatus(Driver, iStep)
         Driver['CAN'].checkReqResp(Driver, "2E F1 A1 FF FF FF FF FF FF FF FF", '6E F1 A1', 0, iStep, True)
         iStep,uds_resp, size = Driver['CAN'].checkReqResp(Driver, '2E 21 00 ' + VariantCoding, '6E 21 00', 0, iStep, False)
         iStep,uds_resp, size = Driver['CAN'].checkReqResp(Driver, '22 21 00', '62 21 00 ' + VariantCoding, 0, iStep, False)

         iStep,uds_resp, size = Driver['CAN'].checkReqResp(Driver, "2E F1 90 00 00 31 32 33 34 35 36 37 38 39 00 00 00 00 00 00", '6E F1 90', 0, iStep, False)
         iStep,uds_resp, size = Driver['CAN'].checkReqResp(Driver, '22 F1 90', '62 F1 90 00 00 31 32 33 34 35 36 37 38 39 00 00 00 00 00 00', 0, iStep, False)

         iStep,uds_resp, size = Driver['CAN'].checkReqResp(Driver, "19 02 09", "59 02 09", 0, iStep, False, 'UDS', 'ClearFault')
         iStep = Driver['CAN'].delInitialFailure(iStep,uds_resp)
      
      Driver['CAN'].wakeup_ctrl(False)

   def checkFailureStatus(self,Driver,iStep = 1):
      current_failure  = [[0x00,0x00,0x00]]
      historical_failure=[[0x00,0x00,0x00]]
      # 获取存在的当前故障
      iStep,uds_resp,size = Driver['CAN'].checkReqResp(Driver, [0x19,0x02,0x09], [0x59,0x02,0x09], 0, iStep, False, 'UDS', 'noClearFault')
      for i in range(3,size,4):
         current_failure.append(uds_resp[i:i+3])
      

      iStep,uds_resp,size = Driver['CAN'].checkReqResp(Driver, [0x19,0x0A], [0x59,0x0A,0x09], 0, iStep, False, 'UDS', 'noClearFault')
      respstr = binascii.b2a_hex(bytearray(uds_resp),' ')
      with allure.step(f"Step{iStep} check failure status:{0}".format(respstr)):
         with assume: assert uds_resp[0:3] == [0x59,0x0A,0x09]
         for i in range(len(Set_up.DTC_list)):
            dtcNumber = Set_up.DTC_list[i][0]
            iStartByte = 3 + i * 4
            with assume: 
               if dtcNumber in current_failure:
                  dtcNumber = dtcNumber + [0x09]
               elif dtcNumber in historical_failure:
                  dtcNumber = dtcNumber + [0x08]
               else:
                  dtcNumber = dtcNumber + [0x00]

               assert uds_resp[iStartByte:(4+iStartByte)] == dtcNumber
            if uds_resp[iStartByte:(4+iStartByte)] != dtcNumber:
               actualRespStr = binascii.b2a_hex(bytearray(uds_resp[iStartByte:(4+iStartByte)]),' ')
               corrRespStr = binascii.b2a_hex(bytearray(dtcNumber),' ')
               logging.error(f'{actualRespStr} != {corrRespStr}')
      iStep += 1

      return iStep